using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace TangHotKey
{
    /// <summary>
    /// 全局热键管理器
    /// </summary>
    public class HotKeyManager : IDisposable
    {
        #region Win32 API
        [DllImport("user32.dll", SetLastError = true)]
        private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);

        [DllImport("user32.dll", SetLastError = true)]
        private static extern bool UnregisterHotKey(IntPtr hWnd, int id);

        private const int WM_HOTKEY = 0x0312;
        #endregion

        #region 修饰键枚举
        [Flags]
        public enum ModifierKeys : uint
        {
            None = 0,
            Alt = 1,
            Control = 2,
            Shift = 4,
            Win = 8
        }
        #endregion

        private readonly Dictionary<int, HotKeyInfo> _hotKeys = new Dictionary<int, HotKeyInfo>();
        private readonly Form _form;
        private int _nextId = 1;
        private bool _disposed = false;

        /// <summary>
        /// 热键信息
        /// </summary>
        private class HotKeyInfo
        {
            public int Id { get; set; }
            public ModifierKeys Modifiers { get; set; }
            public Keys Key { get; set; }
            public Action Callback { get; set; }
            public string Description { get; set; }
        }

        /// <summary>
        /// 已注册热键信息（用于兼容.NET Framework 4.6.x）
        /// </summary>
        public class RegisteredHotKeyInfo
        {
            public int Id { get; set; }
            public ModifierKeys Modifiers { get; set; }
            public Keys Key { get; set; }
            public string Description { get; set; }

            public RegisteredHotKeyInfo(int id, ModifierKeys modifiers, Keys key, string description)
            {
                Id = id;
                Modifiers = modifiers;
                Key = key;
                Description = description;
            }
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="form">用于接收热键消息的窗体</param>
        public HotKeyManager(Form form)
        {
            _form = form ?? throw new ArgumentNullException(nameof(form));
            
            // 创建消息处理器
            var messageHandler = new HotKeyMessageHandler(this);
            messageHandler.AssignHandle(_form.Handle);
        }

        /// <summary>
        /// 注册热键
        /// </summary>
        /// <param name="modifiers">修饰键</param>
        /// <param name="key">主键</param>
        /// <param name="callback">回调函数</param>
        /// <param name="description">描述</param>
        /// <returns>热键ID，失败返回-1</returns>
        public int RegisterHotKey(ModifierKeys modifiers, Keys key, Action callback, string description = "")
        {
            if (callback == null)
                throw new ArgumentNullException(nameof(callback));

            int id = _nextId++;
            
            if (RegisterHotKey(_form.Handle, id, (uint)modifiers, (uint)key))
            {
                var hotKeyInfo = new HotKeyInfo
                {
                    Id = id,
                    Modifiers = modifiers,
                    Key = key,
                    Callback = callback,
                    Description = description
                };
                
                _hotKeys[id] = hotKeyInfo;
                return id;
            }
            
            return -1;
        }

        /// <summary>
        /// 注销热键
        /// </summary>
        /// <param name="hotKeyId">热键ID</param>
        /// <returns>是否成功</returns>
        public bool UnregisterHotKey(int hotKeyId)
        {
            if (_hotKeys.ContainsKey(hotKeyId))
            {
                bool result = UnregisterHotKey(_form.Handle, hotKeyId);
                if (result)
                {
                    _hotKeys.Remove(hotKeyId);
                }
                return result;
            }
            return false;
        }

        /// <summary>
        /// 获取所有已注册的热键信息
        /// </summary>
        /// <returns>热键信息列表</returns>
        public List<RegisteredHotKeyInfo> GetRegisteredHotKeys()
        {
            var result = new List<RegisteredHotKeyInfo>();
            foreach (var hotKey in _hotKeys.Values)
            {
                result.Add(new RegisteredHotKeyInfo(hotKey.Id, hotKey.Modifiers, hotKey.Key, hotKey.Description));
            }
            return result;
        }



        /// <summary>
        /// 处理热键消息
        /// </summary>
        /// <param name="m">Windows消息</param>
        internal void ProcessHotKeyMessage(ref Message m)
        {
            if (m.Msg == WM_HOTKEY)
            {
                int id = m.WParam.ToInt32();
                if (_hotKeys.ContainsKey(id))
                {
                    try
                    {
                        _hotKeys[id].Callback?.Invoke();
                    }
                    catch (Exception ex)
                    {
                        // 可以添加日志记录
                        System.Diagnostics.Debug.WriteLine($"热键回调执行出错: {ex.Message}");
                    }
                }
            }
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            if (!_disposed)
            {
                // 注销所有热键
                var hotKeyIds = new List<int>(_hotKeys.Keys);
                foreach (int id in hotKeyIds)
                {
                    UnregisterHotKey(id);
                }
                
                _disposed = true;
            }
        }

        /// <summary>
        /// 热键消息处理器
        /// </summary>
        private class HotKeyMessageHandler : NativeWindow
        {
            private readonly HotKeyManager _manager;

            public HotKeyMessageHandler(HotKeyManager manager)
            {
                _manager = manager;
            }

            protected override void WndProc(ref Message m)
            {
                _manager.ProcessHotKeyMessage(ref m);
                base.WndProc(ref m);
            }
        }
    }
}